import { Injectable } from '@nestjs/common';
import * as fs from 'fs';
import * as path from 'path';
import * as archiver from 'archiver';
import { IProject } from 'src/types/projects';

@Injectable()
export class ProjectService {
  private exportBasePath = process.env.projectSaveZipPath || '../../Output'; // 文件存储目录
  private projectBasePath = process.env.projectSavePath || '../../Output'; // 文件存储目录

  /**
   * 创建项目并返回下载地址
   * @param dirData IDirData 数据
   * @returns 压缩包的下载 URL
   */
  async createProject(dirData: IProject, isZip?: boolean): Promise<string> {
    const projectPath = isZip ? path.join(this.exportBasePath, dirData.projectName) : path.join(this.projectBasePath, dirData.projectName);
    console.log('创建项目路径：', projectPath);
    const zipFilePath = `${projectPath}.zip`;
    // 确保输出目录存在
    if (!fs.existsSync(this.exportBasePath)) {
      fs.mkdirSync(this.exportBasePath, { recursive: true });
    }

    // 创建文件夹结构
    await this.saveDirDataToLocal(dirData, projectPath);
    if (isZip) {
      // 压缩文件夹为 ZIP
      await this.compressFolder(projectPath, zipFilePath);

      // 删除临时项目文件夹
      this.removeFolder(projectPath);

      // 返回下载地址
      return `/download/${dirData.projectName}.zip`;
    }
    return projectPath;
  }

  async updateProject(dirData: IProject) {
    const projectPath = path.join(this.projectBasePath, dirData.projectName);
    // 创建文件夹结构
    // 确保输出目录存在
    if (!fs.existsSync(this.exportBasePath)) {
      fs.mkdirSync(this.exportBasePath, { recursive: true });
    }
    await this.saveDirDataToLocal(dirData, projectPath);
    return projectPath;
  }

  /**
   * 保存 IDirData 为文件夹
   */
  private async saveDirDataToLocal(dirData: IProject, basePath: string) {
    for (const file of dirData.content) {
      const fullPath = path.join(basePath, file.path);
      const dirPath = path.dirname(fullPath);

      // 创建文件夹路径
      if (!fs.existsSync(dirPath)) {
        fs.mkdirSync(dirPath, { recursive: true });
      }

      // 写入文件
      fs.writeFileSync(fullPath, file.code, 'utf-8');
    }
  }

  /**
   * 压缩文件夹为 ZIP
   */
  private async compressFolder(source: string, out: string): Promise<void> {
    return new Promise((resolve, reject) => {
      const output = fs.createWriteStream(out);
      const archive = archiver('zip', { zlib: { level: 9 } });

      output.on('close', resolve);
      archive.on('error', reject);

      archive.pipe(output);
      archive.directory(source, false);
      archive.finalize();
    });
  }

  /**
   * 删除文件夹
   */
  private removeFolder(folderPath: string) {
    if (fs.existsSync(folderPath)) {
      fs.rmSync(folderPath, { recursive: true, force: true });
    }
  }
}
